Skip to content

Configure Flipper server open URL, plugin install, and activation - #24

Open
sugarmanz wants to merge 3 commits into
mainfrom
flipper-server-config
Open

Configure Flipper server open URL, plugin install, and activation#24
sugarmanz wants to merge 3 commits into
mainfrom
flipper-server-config

Conversation

@sugarmanz

@sugarmanz sugarmanz commented Sep 9, 2026

Copy link
Copy Markdown
Member

Summary

Gives FlipperServerTransport control over three things that previously required a manual Flipper desktop app:

  • Configurable browser open/URLopen/url constructor options (env vars PLAYER_DEVTOOLS_FLIPPER_OPEN/PLAYER_DEVTOOLS_FLIPPER_URL in the CLI). Off by default; when enabled, opens a caller-supplied URL instead of always opening http://localhost:52342. flipper-server itself is always launched with --open=false and browser-opening is now driven by the transport.
  • Plugin installationensurePluginInstalled() uses Flipper's own documented plugin-management RPCs (plugins-get-installed-plugins, plugins-install-from-npm) — the same commands the desktop UI's "Install Plugin" button calls — instead of reaching into ~/.flipper/installed-plugins or shelling out to this repo's local just install-flipper-client recipe. flipper-plugin-player-ui-devtools is already published to npm, so this works for any consumer of @player-devtools/mcp, not just repo checkouts.
  • Plugin activationenablePlugin(clientId?)/disablePlugin(clientId?) send the init/deinit handshake Flipper's device SDK requires before it will open a live plugin connection and relay messages. Nothing in flipper-server sends this automatically for a non-background, foreground-only plugin like ours without a full desktop Flipper app attached with the plugin's tab selected — these methods let a caller trigger the same handshake directly. enablePlugin() always calls ensurePluginInstalled() first (the plugin can be installed/removed on the attached flipper-server independently of this transport, so there's no "already installed" snapshot that stays trustworthy across calls), and skips clients it already believes are active; disablePlugin() without a clientId only targets clients it believes are active. An opt-in autoEnablePlugin constructor flag (used by bin/run) calls enablePlugin(clientId) automatically for every connecting client.

The CLI (player-devtools-mcp/bin/run) sets autoEnablePlugin: true, so every connecting client gets the plugin installed (if needed) and activated automatically as it connects — no manual Flipper UI interaction or separate startup step required.

Test plan

  • bazel test //devtools/client/flipper:flipper_eslint //devtools/client/flipper:flipper_vitest //devtools/mcp:mcp_eslint //devtools/mcp:mcp_vitest — all pass
  • bazel build //devtools/mcp:mcp_ts_types_transitive_typecheck_test — passes across both packages
  • Manual: run player-devtools-mcp with a Player app instance connected as a device and no Flipper desktop UI running; confirm list_players/get_player_status succeed without any manual Flipper UI interaction
  • Manual: confirm PLAYER_DEVTOOLS_FLIPPER_OPEN=true PLAYER_DEVTOOLS_FLIPPER_URL=https://player-ui.tools:52342 opens the custom URL instead of localhost:52342

Release Notes

@player-devtools/mcp no longer requires any manual Flipper desktop app interaction to install or activate the Player UI Devtools plugin — the MCP server now installs the plugin (via Flipper's own plugin-management API) and activates it automatically for each connecting device. FlipperServerTransport gains open/url options for controlling whether/where a browser UI opens (env vars PLAYER_DEVTOOLS_FLIPPER_OPEN/PLAYER_DEVTOOLS_FLIPPER_URL for the CLI), and new ensurePluginInstalled()/enablePlugin()/disablePlugin() methods for consumers embedding the transport directly.

📦 Published PR as canary version: 0.14.3--canary.24.1158

Try this version out locally by upgrading relevant packages to 0.14.3--canary.24.1158

@sugarmanz

Copy link
Copy Markdown
Member Author

/canary

@AngelaVilladiego

Copy link
Copy Markdown

Canary version successfully sends the init message and works with dynex studio.

@sugarmanz
sugarmanz marked this pull request as ready for review September 11, 2026 23:02
@sugarmanz
sugarmanz requested a review from a team as a code owner September 11, 2026 23:02
@sugarmanz
sugarmanz enabled auto-merge (squash) September 11, 2026 23:03
@sugarmanz
sugarmanz disabled auto-merge September 11, 2026 23:13
Give FlipperServerTransport control over three things that previously
required a manual Flipper desktop app: a configurable browser-open URL
(instead of always opening http://localhost:52342), installing the
devtools plugin via Flipper's documented plugins-install-from-npm RPC
(instead of requiring the repo's local justfile/Bazel tooling), and
explicit enablePlugin/disablePlugin methods that send the init/deinit
handshake Flipper's device SDK requires before it will relay plugin
messages — something flipper-server never does on its own for a
non-background plugin without a desktop UI attached.
@sugarmanz
sugarmanz force-pushed the flipper-server-config branch from 85f1ed0 to f585552 Compare September 11, 2026 23:23
ensurePluginInstalled() now runs inside enablePlugin() itself rather
than once in the client-connected handler, since the plugin can be
installed/removed on the attached flipper-server independently of
this transport (e.g. a human using the desktop UI concurrently) — a
cached "already installed" snapshot can't be trusted across calls.

sendLifecycleMessage's implicit target list is now computed by
enablePlugin/disablePlugin themselves (the layer that owns the
init/deinit semantics) instead of embedding method-specific dedup
logic inside the generic send helper: enablePlugin skips clients
already believed active, disablePlugin only targets clients believed
active.
@sugarmanz
sugarmanz enabled auto-merge (squash) September 12, 2026 00:12
Install and activation now happen lazily inside enablePlugin(), triggered
per client-connected event via autoEnablePlugin — not as a one-time step
when bin/run starts, which is what the docs still said after the previous
commit moved ensurePluginInstalled() out of bin/run and into enablePlugin().
@sugarmanz

Copy link
Copy Markdown
Member Author

/canary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants